package com.iplant.ams.serviceImpl.dao.dms.maintenance;

import com.iplant.ams.service.po.dms.DMSDeviceLedger;
import com.iplant.ams.service.po.dms.maintenance.*;
import com.iplant.ams.serviceImpl.DRMServiceImpl;
import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.enums.DBSchemas;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.BaseDAO;
import com.iplant.basic.service.po.bms.BMSEmployee;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

public class DMSMaintenanceTaskDAO extends BaseDAO {

    private static final Logger logger = LoggerFactory.getLogger(DMSMaintenanceTaskDAO.class);

    private static DMSMaintenanceTaskDAO Instance = null;

    private DMSMaintenanceTaskDAO() {
        super();
    }

    public static DMSMaintenanceTaskDAO getInstance() {
        if (Instance == null)
            Instance = new DMSMaintenanceTaskDAO();
        return Instance;
    }

    public List<DMSDeviceLedger> DMS_SelectDeviceLedgerList(BMSEmployee wLoginUser, String wCode, String wName,
                                                            int wFactoryID, int wWorkShopID, int wWorkAreaID,
                                                            Pagination wPagination, OutResult<Integer> wErrorCode) {
        List<DMSDeviceLedger> wResultList = new ArrayList<>();
        try {

            String wSQLText = StringUtils.Format("SELECT t.ID,t9.Code,t9.Name FROM {0}.dms_device_ledger t "
                            + " left join {0}.ams_asset_list t9 on t.AssetInfoID=t9.ID "
                            + " left join {1}.fmc_workarea t1 on t.WorkAreaID=t1.ID "
                            + " left join {1}.fmc_workshop t2 on t1.WorkshopID=t2.ID "
                            + "where 1=1 " +
                            "and t9.Active=1 "
                            + "and ( :wFactoryID <=0 or t2.FactoryID = :wFactoryID) "
                            + "and ( :wWorkShopID <=0 or t1.WorkShopID = :wWorkShopID) "
                            + "and ( :wWorkAreaID <=0 or t.WorkAreaID = :wWorkAreaID) "
                            + " and(:Code is null or :Code = '''' or t9.Code like :Code)"
                            + " and(:Name is null or :Name = '''' or t9.Name like :Name)", DBSchemas.AMS.getDBName(),
                    DBSchemas.Basic.getDBName());

            Map<String, Object> wParms = new HashMap<>();
            wParms.put("Code", StringUtils.isEmpty(wCode) ? wCode : "%" + wCode + "%");
            wParms.put("Name", StringUtils.isEmpty(wName) ? wName : "%" + wName + "%");
            wParms.put("wFactoryID", wFactoryID);
            wParms.put("wWorkShopID", wWorkShopID);
            wParms.put("wWorkAreaID", wWorkAreaID);

            List<Map<String, Object>> wQueryResultList = this.queryForList(wSQLText, wParms, wPagination);

            DMSDeviceLedger wDMSMaintenanceTask;
            for (Map<String, Object> wSqlDataReader : wQueryResultList) {
                wDMSMaintenanceTask = new DMSDeviceLedger();

                wDMSMaintenanceTask.ID = StringUtils.parseInt(wSqlDataReader.get("ID"));
                wDMSMaintenanceTask.Code = StringUtils.parseString(wSqlDataReader.get("Code"));
                wDMSMaintenanceTask.Name = StringUtils.parseString(wSqlDataReader.get("Name"));

                wResultList.add(wDMSMaintenanceTask);
            }
        } catch (Exception ex) {
            logger.error("DMS_SelectDeviceLedgerList", ex);
            wErrorCode.Result = ExceptionTypes.DBSQL.getValue();
        }
        return wResultList;
    }

    public List<DMSMaintenanceTask> DMS_QueryToDayTaskList(BMSEmployee wLoginUser, int wType,
                                                           OutResult<Integer> wErrorCode) {
        List<DMSMaintenanceTask> wResultList = new ArrayList<>();
        try {
            String wSQLText = StringUtils.Format("SELECT distinct t.*,t1.Name CreatorName,t2.Name EditorName,t9.Code " +
                            "DeviceCode,t9.Name DeviceName,t4.Name DispatchPersonName,t5.Name CheckerName  FROM " +
                            "{1}.dms_maintenance_task t "
                            + " left join {0}.mbs_user t1 on t.CreatorID=t1.ID "
                            + " left join {0}.mbs_user t2 on t.EditorID=t2.ID "
                            + " left join {1}.dms_device_ledger t3 on t.DeviceID=t3.ID "
                            + " left join {0}.mbs_user t4 on t.DispatchPersonID=t4.ID "
                            + " left join {0}.mbs_user t5 on t.CheckerID=t5.ID "
                            + " left join {1}.ams_asset_list t9 on t3.AssetInfoID=t9.ID "
                            + " left join {1}.dms_maintenance_item_task t10 on t10.TaskID=t.ID "
                            + " left join {1}.dms_maintenance_item t11 on t10.MaintenanceItemID=t11.ID "
                            + " WHERE (t.Status=1 or (t.Status=2 and t.EditTime>:StartTime and t.EditTime<:EndTime) )"
                            + "and ( :wType <=0 or t11.Type = :wType) " +
                            " ",
                    DBSchemas.Basic.getDBName(), DBSchemas.AMS.getDBName());

            Map<String, Object> wParms = new HashMap<>();

            // 今日时间
            Calendar wTodaySTime = Calendar.getInstance();
            wTodaySTime.set(Calendar.HOUR_OF_DAY, 0);
            wTodaySTime.set(Calendar.MINUTE, 0);
            wTodaySTime.set(Calendar.SECOND, 0);
            Calendar wTodayETime = Calendar.getInstance();
            wTodayETime.set(Calendar.HOUR_OF_DAY, 23);
            wTodayETime.set(Calendar.MINUTE, 59);
            wTodayETime.set(Calendar.SECOND, 59);

            wParms.put("StartTime", wTodaySTime);
            wParms.put("EndTime", wTodayETime);
            wParms.put("wType", wType);

            List<Map<String, Object>> wQueryResultList = this.queryForList(wSQLText, wParms);

            DMSMaintenanceTask wDMSMaintenanceTask;
            for (Map<String, Object> wSqlDataReader : wQueryResultList) {
                wDMSMaintenanceTask = new DMSMaintenanceTask();
                wDMSMaintenanceTask.ID = StringUtils.parseInt(wSqlDataReader.get("ID"));
                wDMSMaintenanceTask.CreatorID = StringUtils.parseInt(wSqlDataReader.get("CreatorID"));
                wDMSMaintenanceTask.CreatorName = StringUtils.parseString(wSqlDataReader.get("CreatorName"));
                wDMSMaintenanceTask.CreateTime = StringUtils.parseCalendar(wSqlDataReader.get("CreateTime"));
                wDMSMaintenanceTask.EditorID = StringUtils.parseInt(wSqlDataReader.get("EditorID"));
                wDMSMaintenanceTask.EditorName = StringUtils.parseString(wSqlDataReader.get("EditorName"));
                wDMSMaintenanceTask.EditTime = StringUtils.parseCalendar(wSqlDataReader.get("EditTime"));
                wDMSMaintenanceTask.Code = StringUtils.parseString(wSqlDataReader.get("Code"));
                wDMSMaintenanceTask.DeviceID = StringUtils.parseInt(wSqlDataReader.get("DeviceID"));
                wDMSMaintenanceTask.DeviceCode = StringUtils.parseString(wSqlDataReader.get("DeviceCode"));
                wDMSMaintenanceTask.DeviceName = StringUtils.parseString(wSqlDataReader.get("DeviceName"));
                wDMSMaintenanceTask.MaintenanceRuleID = StringUtils.parseInt(wSqlDataReader.get("MaintenanceRuleID"));
                wDMSMaintenanceTask.DispatchPersonID = StringUtils.parseInt(wSqlDataReader.get("DispatchPersonID"));
                wDMSMaintenanceTask.DispatchPersonName = StringUtils.parseString(wSqlDataReader.get(
                        "DispatchPersonName"));
                wDMSMaintenanceTask.DispatchTime = StringUtils.parseCalendar(wSqlDataReader.get("DispatchTime"));
                wDMSMaintenanceTask.DispatchRemark = StringUtils.parseString(wSqlDataReader.get("DispatchRemark"));
                wDMSMaintenanceTask.CheckerID = StringUtils.parseInt(wSqlDataReader.get("CheckerID"));
                wDMSMaintenanceTask.CheckerName = StringUtils.parseString(wSqlDataReader.get("CheckerName"));
                wDMSMaintenanceTask.CheckerTime = StringUtils.parseCalendar(wSqlDataReader.get("CheckerTime"));
                wDMSMaintenanceTask.CheckerRemark = StringUtils.parseString(wSqlDataReader.get("CheckerRemark"));
                wDMSMaintenanceTask.Remark = StringUtils.parseString(wSqlDataReader.get("Remark"));
                wDMSMaintenanceTask.Result = StringUtils.parseInt(wSqlDataReader.get("Result"));
                wDMSMaintenanceTask.Status = StringUtils.parseInt(wSqlDataReader.get("Status"));

                wResultList.add(wDMSMaintenanceTask);
            }
        } catch (Exception ex) {
            logger.error("DMS_QueryToDayTaskList", ex);
            wErrorCode.Result = ExceptionTypes.DBSQL.getValue();
        }
        return wResultList;
    }

    public List<DMSDeviceLedger> DMS_SelectDeviceLedgerListToRepair(BMSEmployee wLoginUser, String wCode,
                                                                    String wName, int wFactoryID, int wWorkShopID,
                                                                    int wWorkAreaID, Pagination wPagination,
                                                                    OutResult<Integer> wErrorCode) {
        List<DMSDeviceLedger> wResultList = new ArrayList<>();
        try {
            String wSQLText = StringUtils.Format("SELECT t.ID,t9.Code,t9.Name FROM {0}.dms_device_ledger t "
                            + " inner join {0}.dms_maintenance_task t1 on t.ID=t1.DeviceID "
                            + " left join {0}.ams_asset_list t9 on t.AssetInfoID=t9.ID "
                            + " left join {1}.fmc_workarea t3 on t.WorkAreaID=t3.ID "
                            + " left join {1}.fmc_workshop t2 on t3.WorkshopID=t2.ID "
                            + " where 1=1 and t9.Active=1 and t1.Status=1 "
                            + "and ( :wFactoryID <=0 or t2.FactoryID = :wFactoryID) "
                            + "and ( :wWorkShopID <=0 or t3.WorkShopID = :wWorkShopID) "
                            + "and ( :wWorkAreaID <=0 or t.WorkAreaID = :wWorkAreaID) "
                            + " and(:Code is null or :Code = '''' or t9.Code like :Code)"
                            + " and(:Name is null or :Name = '''' or t9.Name like :Name)", DBSchemas.AMS.getDBName(),
                    DBSchemas.Basic.getDBName());

            Map<String, Object> wParams = new HashMap<String, Object>();
            wParams.put("Code", StringUtils.isEmpty(wCode) ? wCode : "%" + wCode + "%");
            wParams.put("Name", StringUtils.isEmpty(wName) ? wName : "%" + wName + "%");
            wParams.put("wFactoryID", wFactoryID);
            wParams.put("wWorkShopID", wWorkShopID);
            wParams.put("wWorkAreaID", wWorkAreaID);

            List<Map<String, Object>> wQueryResultList = this.queryForList(wSQLText, wParams, wPagination);

            DMSDeviceLedger wDMSMaintenanceTask;
            for (Map<String, Object> wSqlDataReader : wQueryResultList) {
                wDMSMaintenanceTask = new DMSDeviceLedger();
                wDMSMaintenanceTask.ID = StringUtils.parseInt(wSqlDataReader.get("ID"));
                wDMSMaintenanceTask.Code = StringUtils.parseString(wSqlDataReader.get("Code"));
                wDMSMaintenanceTask.Name = StringUtils.parseString(wSqlDataReader.get("Name"));

                wResultList.add(wDMSMaintenanceTask);
            }
        } catch (Exception ex) {
            logger.error("DMS_SelectDeviceLedgerListToRepair", ex);
            wErrorCode.Result = ExceptionTypes.DBSQL.getValue();
        }
        return wResultList;
    }

    public List<DMSDeviceLedger> DMS_SelectDeviceLedgerListRepaired(BMSEmployee wLoginUser, String wCode,
                                                                    String wName, int wFactoryID, int wWorkShopID,
                                                                    int wWorkAreaID, Pagination wPagination,
                                                                    OutResult<Integer> wErrorCode) {
        List<DMSDeviceLedger> wResultList = new ArrayList<>();
        try {
            String wSQLText = StringUtils.Format("SELECT t.ID,t9.Code,t9.Name FROM {0}.dms_device_ledger t "
                            + " inner join {0}.dms_maintenance_task t1 on t.ID=t1.DeviceID "
                            + " left join {0}.ams_asset_list t9 on t.AssetInfoID=t9.ID "
                            + " left join {1}.fmc_workarea t3 on t.WorkAreaID=t3.ID "
                            + " left join {1}.fmc_workshop t2 on t3.WorkshopID=t2.ID "
                            + " where 1=1 and t9.Active=1 and t1.Status=2 and  t1.EditTime>:StartTime and t1" +
                            ".EditTime<:EndTime "
                            + "and ( :wFactoryID <=0 or t2.FactoryID = :wFactoryID) "
                            + "and ( :wWorkShopID <=0 or t3.WorkShopID = :wWorkShopID) "
                            + "and ( :wWorkAreaID <=0 or t.WorkAreaID = :wWorkAreaID) "
                            + " and(:Code is null or :Code = '''' or t9.Code like :Code)"
                            + " and(:Name is null or :Name = '''' or t9.Name like :Name)", DBSchemas.AMS.getDBName(),
                    DBSchemas.Basic.getDBName());

            Map<String, Object> wParms = new HashMap<>();

            // 今日时间
            Calendar wTodaySTime = Calendar.getInstance();
            wTodaySTime.set(Calendar.HOUR_OF_DAY, 0);
            wTodaySTime.set(Calendar.MINUTE, 0);
            wTodaySTime.set(Calendar.SECOND, 0);
            Calendar wTodayETime = Calendar.getInstance();
            wTodayETime.set(Calendar.HOUR_OF_DAY, 23);
            wTodayETime.set(Calendar.MINUTE, 59);
            wTodayETime.set(Calendar.SECOND, 59);

            wParms.put("StartTime", wTodaySTime);
            wParms.put("EndTime", wTodayETime);
            wParms.put("Code", StringUtils.isEmpty(wCode) ? wCode : "%" + wCode + "%");
            wParms.put("Name", StringUtils.isEmpty(wName) ? wName : "%" + wName + "%");
            wParms.put("wFactoryID", wFactoryID);
            wParms.put("wWorkShopID", wWorkShopID);
            wParms.put("wWorkAreaID", wWorkAreaID);

            List<Map<String, Object>> wQueryResultList = this.queryForList(wSQLText, wParms, wPagination);

            DMSDeviceLedger wDMSMaintenanceTask;
            for (Map<String, Object> wSqlDataReader : wQueryResultList) {
                wDMSMaintenanceTask = new DMSDeviceLedger();

                wDMSMaintenanceTask.ID = StringUtils.parseInt(wSqlDataReader.get("ID"));
                wDMSMaintenanceTask.Code = StringUtils.parseString(wSqlDataReader.get("Code"));
                wDMSMaintenanceTask.Name = StringUtils.parseString(wSqlDataReader.get("Name"));

                wResultList.add(wDMSMaintenanceTask);
            }
        } catch (Exception ex) {
            logger.error("DMS_SelectDeviceLedgerListRepaired", ex);
            wErrorCode.Result = ExceptionTypes.DBSQL.getValue();
        }
        return wResultList;
    }

    public List<DMSDeviceLedger> DMS_SelectDeviceLedgerListNotRepair(BMSEmployee wLoginUser, String wCode,
                                                                     String wName, int wFactoryID, int wWorkShopID,
                                                                     int wWorkAreaID, Pagination wPagination,
                                                                     OutResult<Integer> wErrorCode) {
        List<DMSDeviceLedger> wResultList = new ArrayList<>();
        try {
            String wSQLText = StringUtils.Format("SELECT t.ID,t9.Code,t9.Name FROM {0}.dms_device_ledger t "
                            + " left join {0}.ams_asset_list t9 on t.AssetInfoID=t9.ID "
                            + " left join {1}.fmc_workarea t1 on t.WorkAreaID=t1.ID "
                            + " left join {1}.fmc_workshop t2 on t1.WorkshopID=t2.ID "
                            + " where 1=1 and t9.Active=1 and t.ID not in (SELECT DeviceID FROM {0}" +
                            ".dms_maintenance_task " +
                            "where " +
                            "(Status=1 or (Status=2 and EditTime>:StartTime and EditTime<:EndTime) )) "
                            + "and ( :wFactoryID <=0 or t2.FactoryID = :wFactoryID) "
                            + "and ( :wWorkShopID <=0 or t1.WorkShopID = :wWorkShopID) "
                            + "and ( :wWorkAreaID <=0 or t.WorkAreaID = :wWorkAreaID) "
                            + " and(:Code is null or :Code = '''' or t9.Code like :Code)"
                            + " and(:Name is null or :Name = '''' or t9.Name like :Name)", DBSchemas.AMS.getDBName(),
                    DBSchemas.Basic.getDBName());

            Map<String, Object> wParms = new HashMap<>();

            // 今日时间
            Calendar wTodaySTime = Calendar.getInstance();
            wTodaySTime.set(Calendar.HOUR_OF_DAY, 0);
            wTodaySTime.set(Calendar.MINUTE, 0);
            wTodaySTime.set(Calendar.SECOND, 0);
            Calendar wTodayETime = Calendar.getInstance();
            wTodayETime.set(Calendar.HOUR_OF_DAY, 23);
            wTodayETime.set(Calendar.MINUTE, 59);
            wTodayETime.set(Calendar.SECOND, 59);

            wParms.put("StartTime", wTodaySTime);
            wParms.put("EndTime", wTodayETime);
            wParms.put("Code", StringUtils.isEmpty(wCode) ? wCode : "%" + wCode + "%");
            wParms.put("Name", StringUtils.isEmpty(wName) ? wName : "%" + wName + "%");
            wParms.put("wFactoryID", wFactoryID);
            wParms.put("wWorkShopID", wWorkShopID);
            wParms.put("wWorkAreaID", wWorkAreaID);

            List<Map<String, Object>> wQueryResultList = this.queryForList(wSQLText, wParms, wPagination);

            DMSDeviceLedger wDMSMaintenanceTask;
            for (Map<String, Object> wSqlDataReader : wQueryResultList) {
                wDMSMaintenanceTask = new DMSDeviceLedger();

                wDMSMaintenanceTask.ID = StringUtils.parseInt(wSqlDataReader.get("ID"));
                wDMSMaintenanceTask.Code = StringUtils.parseString(wSqlDataReader.get("Code"));
                wDMSMaintenanceTask.Name = StringUtils.parseString(wSqlDataReader.get("Name"));

                wResultList.add(wDMSMaintenanceTask);
            }
        } catch (Exception ex) {
            logger.error("DMS_SelectDeviceLedgerListNotRepair", ex);
            wErrorCode.Result = ExceptionTypes.DBSQL.getValue();
        }
        return wResultList;
    }

    /**
     * 自动触发任务
     */
    public void DMS_AutoTriggerTask(BMSEmployee wLoginUser, DMSMaintenanceRule wDMSMaintenanceRule,
                                    DMSMaintenanceRuleItem wDMSMaintenanceRuleItem,
                                    DMSMaintenanceItem wDMSMaintenanceItem,
                                    OutResult<Integer> wErrorCode) {
        try {
            DMSMaintenanceItemTask wTask = new DMSMaintenanceItemTask();
            wTask.DeviceID = wDMSMaintenanceItem.DeviceID;
            wTask.DeviceName = wDMSMaintenanceItem.DeviceName;
            wTask.ConfigurationID = wDMSMaintenanceItem.ConfigurationID;
            wTask.ConfigurationName = wDMSMaintenanceItem.ConfigurationName;
            wTask.MaintenanceItemID = wDMSMaintenanceItem.ID;
            wTask.MaintenanceItemName = wDMSMaintenanceItem.Name;
            wTask.MaintenanceItemDescription = wDMSMaintenanceItem.Description;
            //调用service触发逻辑
            DRMServiceImpl.getInstance().DMS_TriggerTaskMaintenanceItem(wLoginUser,
                    new ArrayList<>(Collections.singletonList(wTask)), wDMSMaintenanceItem.Type);
        } catch (Exception ex) {
            logger.error("DMS_AutoTriggerTask", ex);
            wErrorCode.Result = ExceptionTypes.DBSQL.getValue();
        }
    }
}
